﻿using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Input;
using MathematicallySafe.Armourer;
using MathematicallySafe.HeadCounter.Commands;
using MathematicallySafe.HeadCounter.Data;
using MathematicallySafe.HeadCounter.Data.Models;
using MathematicallySafe.HeadCounter.Services;
using StructureMap;

namespace MathematicallySafe.HeadCounter.ViewModels
{
    public class HeadCounterViewModel : ViewModelBase
    {
        private readonly IHeadCounterService _headCounterService = ObjectFactory.GetInstance<IHeadCounterService>();
        private readonly IArmouryService _armouryService = ArmouryServiceFactory.Instance.GetArmouryService();
        private readonly IPublishingService _publishingService = ObjectFactory.GetInstance<IPublishingService>();

        private readonly Options _options = ObjectFactory.GetInstance<IHeadCounterService>().Options;
        private readonly UserOptions _userOptions = ObjectFactory.GetInstance<IHeadCounterService>().UserOptions;

        private bool _statusMessageActive;
        private string _statusMessage;

        private DelegateCommand _exitCommand;
        private DelegateCommand _exportHtmlCommand;
        private DelegateCommand _exportLuaCommand;
        private DelegateCommand _exportAllCommand;
        private DelegateCommand _publishCommand;
        private DelegateCommand _synchCommand;

        public string GuildName
        {
            get { return _headCounterService.Options.GuildName.ToUpper(); }
        }

        #region Armoury

        protected override void SubscribeEvents()
        {
            _armouryService.ArmouryServiceProgressChanged += ArmouryServiceProgressChanged;
            _armouryService.ArmouryServiceCompleted += ArmouryServiceCompleted;
        }

        protected override void UnsubscribeEvents()
        {
            _armouryService.ArmouryServiceProgressChanged -= ArmouryServiceProgressChanged;
            _armouryService.ArmouryServiceCompleted -= ArmouryServiceCompleted;
        }

        void ArmouryServiceProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            StatusMessage = (string) e.UserState;
            StatusMessageActive = true;
        }

        void ArmouryServiceCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            StatusMessage = "";
            StatusMessageActive = false;
        }

        public bool StatusMessageActive
        {
            get { return _statusMessageActive; }
            set
            {
                _statusMessageActive = value;
                OnPropertyChanged("StatusMessageActive");
            }
        }

        public string StatusMessage
        {
            get { return _statusMessage; }
            set
            {
                _statusMessage = value;
                OnPropertyChanged("StatusMessage");
            }
        }

        #endregion

        #region Exit Command

        public ICommand ExitCommand
        {
            get
            {
                if (_exitCommand == null)
                {
                    _exitCommand = new DelegateCommand(Exit);
                }

                return _exitCommand;
            }
        }

        private void Exit()
        {
            _headCounterService.Save();
            System.Windows.Application.Current.Shutdown();
        }

        #endregion

        #region Export HTML Command

        public ICommand ExportHtmlCommand
        {
            get
            {
                if (_exportHtmlCommand == null)
                {
                    _exportHtmlCommand = new DelegateCommand(ExportHtml, CanExportHtml);
                }

                return _exportHtmlCommand;
            }
        }

        private void ExportHtml()
        {
            ObjectFactory.GetInstance<IExportService>().Export(ExportType.Html);
        }

        private bool CanExportHtml()
        {
            return _headCounterService.RaidHistory.HasRaids;
        }

        #endregion

        #region Export Lua Command

        public ICommand ExportLuaCommand
        {
            get
            {
                if (_exportLuaCommand == null)
                {
                    _exportLuaCommand = new DelegateCommand(ExportLua, CanExportLua);
                }

                return _exportLuaCommand;
            }
        }

        private void ExportLua()
        {
            ObjectFactory.GetInstance<IExportService>().Export(ExportType.Lua);
        }

        private bool CanExportLua()
        {
            return Directory.Exists(_headCounterService.UserOptions.HeadCounterPath) && _headCounterService.RaidHistory.HasRaids;
        }

        #endregion

        #region Export All Command

        public ICommand ExportAllCommand
        {
            get
            {
                if (_exportAllCommand == null)
                {
                    _exportAllCommand = new DelegateCommand(ExportAll, CanExportAll);
                }

                return _exportAllCommand;
            }
        }

        private void ExportAll()
        {
            ExportHtml();
            ExportLua();
        }

        private bool CanExportAll()
        {
            return CanExportHtml() && CanExportLua();
        }

        #endregion

        #region Publish Command

        public ICommand PublishCommand
        {
            get
            {
                if (_publishCommand == null)
                {
                    _publishCommand = new DelegateCommand(Publish, CanPublish);
                }

                return _publishCommand;
            }
        }

        private void Publish()
        {
            _publishingService.PublishingServiceProgressChanged += PublishingServiceProgressChanged;
            _publishingService.PublishingServiceCompleted += PublishingServiceCompleted;
            _publishingService.RunPublishingServiceAsync();
        }

        private bool CanPublish()
        {
            return IsFTPSetup() && !_publishingService.IsWorking();
        }

        private bool IsFTPSetup()
        {
            return !string.IsNullOrEmpty(_userOptions.FTPDomain) && !string.IsNullOrEmpty(_userOptions.FTPUserName) &&
                   !string.IsNullOrEmpty(_userOptions.FTPPassword) && !string.IsNullOrEmpty(_userOptions.FTPPath);
        }

        void PublishingServiceProgressChanged(object sender, ProgressChangedEventArgs e)
        {
        }

        void PublishingServiceCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _publishingService.PublishingServiceProgressChanged -= PublishingServiceProgressChanged;
            _publishingService.PublishingServiceCompleted -= PublishingServiceCompleted;
        }

        #endregion


        #region Synch Command

        public ICommand SynchCommand
        {
            get
            {
                if (_synchCommand == null)
                {
                    _synchCommand = new DelegateCommand(Sync, CanSync);
                }

                return _synchCommand;
            }
        }

        private void Sync()
        {
        }

        private bool CanSync()
        {
            return false;
        }

        #endregion

    }
}